import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;

public class LFSR_old {

	LinkedList<Integer> lfsr = new LinkedList<Integer>();

	// LinkedList<Integer> polinom=new LinkedList<Integer>();
	LinkedList<Polinom> polinomList = new LinkedList<Polinom>();

	int dolzina = 12;

	public LFSR_old() {

		// generiranje na vrednosti
		/*
		 * Random r=new Random(); Calendar calendar=new GregorianCalendar();
		 * 
		 * for(int i=0;i<this.dolzina;i++){
		 * 
		 * int bit=r.nextInt((int)((calendar.getTimeInMillis())%30001+1));
		 * this.lfsr.add(new Integer(bit%2)); }
		 */

		//prv test 110010100100
		lfsr.add(1);
		lfsr.add(1);
		lfsr.add(0);
		lfsr.add(0);
		lfsr.add(1);
		lfsr.add(0);
		lfsr.add(1);
		lfsr.add(0);
		lfsr.add(0);
		lfsr.add(1);
		lfsr.add(0);
		lfsr.add(0);
		
		/*
		//vtor test
		lfsr.add(1);
		lfsr.add(1);
		lfsr.add(1);
		lfsr.add(1);
		lfsr.add(1);
		lfsr.add(1);
		lfsr.add(1);
		lfsr.add(1);
		lfsr.add(1);
		lfsr.add(1);
		lfsr.add(1);
		lfsr.add(1);
		*/
	
		/*
		//tret test
		lfsr.add(0);
		lfsr.add(0);
		lfsr.add(0);
		lfsr.add(0);
		lfsr.add(0);
		lfsr.add(0);
		lfsr.add(0);
		lfsr.add(0);
		lfsr.add(0);
		lfsr.add(0);
		lfsr.add(0);
		lfsr.add(0);
		
		*/
	}

	public String toString() {

		return this.lfsr.toString();

	}

	// presmetka za dolzina na lfsr-to
	public void setDolzina() {
		this.dolzina = 12;
	}

	public LinkedList<Polinom> getPolinom(String fileName) throws IOException {

		// LinkedList<Polinom> polinomList=new LinkedList<Polinom>();
		BufferedReader read = new BufferedReader(new FileReader(fileName));
		Polinom tmp;
		String r;

		while ((r = read.readLine()) != null) {

			// pomosna promenliva za vnesuvanje na polinomite
			tmp = new Polinom();
			// vnesi ja kvazigrupata
			tmp.setQuasigroup(Integer.parseInt(r));
			tmp.setPolinomi(read.readLine());
			tmp.setPolinomi(read.readLine());
			tmp.setPolinomi(read.readLine());

			this.polinomList.add(tmp);
		}

		read.close();
		return polinomList;
	}

	public String generateLfsr(String polinom1) {

		int bit_feedback1;

		polinom1 = polinom1.replaceAll("\\s", "");
		String[] pomPolinom1 = polinom1.split("\\+");
		String[] monom1;

		/*
		 * ----------------------- Inicijaliziranje na bit_feedback
		 * --------------------------
		 */
		int pozicija;
		int pomBit1;

		// ************************* POLINOM1 *********************
		// ako imame 1 na pocetokot na polinomot
		if (pomPolinom1[0].length() < 2) {
			bit_feedback1 = 1;
		}

		// ako monomot ni e x1 zapisuvame 0 (bidejki nizata na lfsr pocinja od
		// 0)
		else if (pomPolinom1[0].length() == 2) {
			pozicija = Integer.parseInt(pomPolinom1[0].substring(1)) - 1;
			bit_feedback1 = this.lfsr.get(pozicija);
		}

		// ako imame monom x1*x2*x3
		else {
			monom1 = pomPolinom1[0].split("\\*");
			pozicija = Integer.parseInt(monom1[0].substring(1)) - 1;
			pomBit1 = this.lfsr.get(pozicija);

			for (int i = 1; i < monom1.length; i++) {
				pozicija = Integer.parseInt(monom1[i].substring(1)) - 1;
				pomBit1 &= this.lfsr.get(pozicija);
			}
			bit_feedback1 = pomBit1;
		}
		// System.out.println("fidback "+bit_feedback);

		for (int i = pomPolinom1.length - 1; i > 0; i--) {

			// ako imame 1 na pocetokot na polinomot
			if (pomPolinom1[i].length() < 2) {
				bit_feedback1 ^= 1;
			}
			// ako monomot ni e x1 zapisuvame 0 (bidejki nizata na lfsr pocinja
			// od 0)
			else if (pomPolinom1[i].length() == 2) {
				pozicija = Integer.parseInt(pomPolinom1[i].substring(1)) - 1;
				bit_feedback1 ^= this.lfsr.get(pozicija);
			}
			// ako imame monom x1*x2*x3
			else {

				monom1 = pomPolinom1[i].split("\\*");
				pozicija = Integer.parseInt(monom1[0].substring(1)) - 1;
				pomBit1 = this.lfsr.get(pozicija);

				for (int j = 1; j < monom1.length; j++) {
					pozicija = Integer.parseInt(monom1[j].substring(1)) - 1;
					pomBit1 &= this.lfsr.get(pozicija);
				}
				bit_feedback1 ^= pomBit1;
			}

		}

		this.lfsr.addFirst(bit_feedback1);
		String out= String.valueOf(this.lfsr.removeLast());

		// System.out.println("out "+bit_feedback);
		return out;

	}

	public String binToHex(String convert) throws IOException {

		String hexa = "";

//		while (convert.length() % 8 != 0) {
//			convert += "0";
//		}
		int br = 0;

		for (int k = 0; k < convert.length();) {
			
			br++;
			int broj = Integer.parseInt(convert.substring(k, k + 4), 2);
			String hexString = Integer.toHexString(broj);
			System.out.println("tukaaa "+hexString);
			if (br == 80) {
				
				hexa+=hexString + "\n";
				br = 0;
			} else {
				hexa+=hexString;
			}
			k += 4;
//System.out.println("h: "+hexa);
		}
	//	out.close();
		return hexa;
	}

	public static void main(String[] args) throws InterruptedException,IOException {
	
		/**
		 * 
		 *  tuka sekoj da si go napise imeto na svojata datoteka na polinomi
		 *  
		 *  Marija -> polinomi1.txt
		 *  Zlatka -> polinomi2.txt
		 *  Damjan -> polinomi3.txt
		 *  Mile -> polinomi4.txt
		 *  Aleksandar -> polinomi5.txt
		 *  Artan -> polinomi6.txt
		 *  
		 * */
		String fileName = "polinomi\\polinomi1.txt";

		LFSR_old l = new LFSR_old();
		BufferedWriter file1;
		BufferedWriter file2;
		BufferedWriter file3;
		LFSR_old lfsr;
		LinkedList<Polinom> polinomList = new LinkedList<Polinom>();
		polinomList = l.getPolinom(fileName);

		LinkedList<String> polinomi;

		for (int i = 0; i < polinomList.size() ; i++) {

			lfsr = new LFSR_old();
			file1 = new BufferedWriter(new FileWriter("datoteki\\q"+ polinomList.get(i).getQuasigroup() + "_1.txt"));
			file2 = new BufferedWriter(new FileWriter("datoteki\\q"+ polinomList.get(i).getQuasigroup() + "_2.txt"));
			file3 = new BufferedWriter(new FileWriter("datoteki\\q"+ polinomList.get(i).getQuasigroup() + "_3.txt"));
			polinomi = polinomList.get(i).getPolinomi();
			String bit = "", bit1="", bit2="";

			/**
			 * za avtomatska postapka j stavete go da ide do 27000000
			 * 
			 * */
			for (int j = 0; j < 45000; j++) {

				 bit = lfsr.generateLfsr(polinomi.get(0));
				 file1.write(bit);
				 file1.flush();
				 
				 bit1 = lfsr.generateLfsr(polinomi.get(1));
				 file2.write(bit1);
				 file2.flush();
				 
				 bit2 = lfsr.generateLfsr(polinomi.get(2));
				 file3.write(bit2);
				 file3.flush();
			}
			polinomi.clear();
			file1.close();
			file2.close();
			file3.close();

		}
	
	}
}
